home *** CD-ROM | disk | FTP | other *** search
- #define C
-
- #undef PROFILE
- #define COUNT
-
- #include "view.h"
- #include "trig.h"
-
- #ifdef __GNUC__
- #include <osbind.h>
- #include <memory.h>
- #else
- #include <tos.h>
- #endif
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define SKY_COLOR 1
- #define FLOOR_COLOR 2
- #define WALL_COLOR 3
- #define RED_COLOR 4
- #define LEDGE_COLOR 5
- #define ZMIN 20L
-
- #define UPPER_TYPE 0
- #define WALL_TYPE 1
- #define LOWER_TYPE 2
-
- extern char hash(side *ThisSide, int wall_type);
- extern void ColDraw(short x, short top, short bottom, char color);
- extern void RowDraw(short y, short left, short right, char color);
-
- void AddFloorUp(short lb, short b, short start, short type);
- void AddFloorDown(short lb, short b, short start, short type);
- void EndFloorUp(short lb, short b, short start, short type);
- void EndFloorDown(short lb, short b, short start, short type);
-
- extern short width;
- extern short height;
-
- extern short flooropt;
- extern short floorcol;
- extern short nofloor;
- extern short wallopt;
- extern short wallcol;
- extern short singlestep;
- extern short showdata;
-
- #ifdef COUNT
- extern long addfloor;
- extern long addfloor_loops;
-
- extern long addwall;
- extern long addwall_loops;
-
- extern long coldraw;
- extern long coldraw_loops;
-
- extern long rowdraw;
- extern long rowdraw_loops;
- #endif
-
- /* These are some yucky global variables. They should probably
- * be moved into the class's member data.
- */
- extern short WallRunCount;
-
- /* Elements of this array indicate if a screen column is completely drawn. */
-
- #if 0
- extern short Col_Done[320];
- #endif
- extern char Col_Done[320]; /* Slightly better for the cache */
-
-
- /* Elements of this array hold indexes into the wall_run array. */
-
- #if 1
- extern short intersections[50][320];
- #endif
-
- /* The number of wall_runs visible on a particular screen column. */
-
- #if 1
- extern short int_count[320];
- #endif
-
- /* MaxY & MinY are the active edge lists for the top & bottom of the screen. */
-
- extern short MaxY[320];
- extern short MinY[320];
-
-
- /* This is the wall_run array. It contains all of the wall_runs which
- * are visible in a single frame.
- */
-
- #if 1
- extern wall_run walls[8000]; /* 320*50 = 16000 */
- #endif
-
- extern short walltop[320];
- extern short wallbottom[320];
-
- /* The next two arrays are used for both floors and ceilings.
- * Elements of this array hold indexes into the floor_run array.
- */
-
- #if 1
- extern floor_run floorlist[200][40];
- #endif
-
- extern short floorlst[200];
- extern short floortex[200];
-
- /* The number of floor_runs visible on a particular screen column. */
-
- extern short runcount[200];
-
-
- /* The offscreen buffer. */
- extern char *screenbuf;
-
-
- /* This function adds the wall_runs and floor_runs to the
- * lists so that they may be drawn to the screen. It also does
- * the perspective calculations on the wall heights.
- */
-
- void AddWall(short sx1, short sx2, short Rb, short Rt, short Rfz, short Rtz)
- {
- long sy1, sy2, sy3, sy4;
- short last_top, last_bottom, last_miny, last_maxy;
- short top, bottom, miny, maxy;
- short x;
-
- /* Project to determine the four y screen coordinates. */
-
- sy1 = (long)height / 2 + ((Rb * invdistance(Rfz)) >> 16); /* bottom left. */
- sy2 = (long)height / 2 + ((Rb * invdistance(Rtz)) >> 16); /* bottom right. */
- sy3 = (long)height / 2 + ((Rt * invdistance(Rtz)) >> 16); /* top right. */
- sy4 = (long)height / 2 + ((Rt * invdistance(Rfz)) >> 16); /* top left. */
-
- #ifdef COUNT
- addwall++;
- #endif
-
- if (sy1 < sy4) { /* Is this really needed? */
- short tmp;
- #if 0
- printf("F");
- #endif
- tmp = sy1;
- sy1 = sy4;
- sy4 = tmp;
- tmp = sy2;
- sy2 = sy3;
- sy3 = tmp;
- }
-
- Wall.y1 = sy4 << 16;
- Wall.y2 = sy1 << 16;
- Wall.dy1 = ((sy3 - sy4) << 16) / (sx2 - sx1);
- Wall.dy2 = ((sy2 - sy1) << 16) / (sx2 - sx1);
-
- if (sx1 < 0) {
- Wall.y1 -= sx1 * Wall.dy1;
- Wall.y2 -= sx1 * Wall.dy2;
- sx1 = 0;
- }
- if (sx2 > width)
- sx2 = width;
-
- last_maxy = MaxY[sx1];
- last_bottom = MaxY[sx1];
- last_top = MinY[sx1];
- last_miny = MinY[sx1];
-
- #ifdef COUNT
- addwall_loops += sx2 - sx1;
- #endif
-
- for(x = sx1;x < sx2;x++) {
- miny = MinY[x];
- maxy = MaxY[x];
- top = (short)(Wall.y1 >> 16);
- bottom = (short)(Wall.y2 >> 16);
-
- #if 0
- if (miny < maxy) {
- if ((top < maxy) && (bottom > miny)) {
- if (top < miny)
- top = miny;
- if (bottom > maxy)
- bottom = maxy;
-
- if (top < bottom) {
- if (!wallopt) {
- walls[WallRunCount].top = top;
- walls[WallRunCount].bottom = bottom;
- intersections[int_count[x]][x] = WallRunCount;
- int_count[x]++;
- } else {
- ColDraw(x, top, bottom, (char)Wall.tex_code);
- #if 0
- walltop[x] = top;
- wallbottom[x] = bottom;
- #endif
- }
- }
- }
- }
- if (Wall.type == UPPER_TYPE) {
- if (!wallcol) {
- walls[WallRunCount].tex_num = LEDGE_COLOR;
- }
- if (bottom > miny)
- MinY[x] = bottom;
- } else if (Wall.type == LOWER_TYPE) {
- if (!wallcol) {
- walls[WallRunCount].tex_num = LEDGE_COLOR;
- }
- if (top < maxy)
- MaxY[x] = top;
- } else if (Wall.type == WALL_TYPE) {
- if (!wallcol) {
- walls[WallRunCount].tex_num = WALL_COLOR;
- }
- if (bottom > miny)
- MinY[x] = bottom;
- if (top < maxy)
- MaxY[x] = top;
- #if 0
- if (MaxY[x] < MinY[x])
- MaxY[x] = MinY[x];
- #endif
- }
- #if 0
- }
- }
- }
- #endif
-
- #endif
-
- if (!nofloor) {
- if ((Wall.type == WALL_TYPE) || (Wall.type == LOWER_TYPE))
- #if 1
- if (bottom < maxy) {
- #else
- if ((bottom < maxy) && (bottom > miny)) {
- #endif
- if (bottom < last_bottom)
- AddFloorUp(last_bottom, bottom, x, LOWER_TYPE);
- if (maxy > last_maxy)
- AddFloorDown(last_maxy, maxy, x, LOWER_TYPE);
- if (bottom > last_bottom)
- EndFloorDown(last_bottom, bottom, x, LOWER_TYPE);
- if (maxy < last_maxy)
- EndFloorUp(last_maxy, maxy, x, LOWER_TYPE);
- } else if (last_bottom < last_maxy)
- EndFloorUp(last_maxy, last_bottom, x, LOWER_TYPE);
-
- if ((Wall.type == WALL_TYPE) || (Wall.type == UPPER_TYPE))
- #if 1
- if (top > miny) {
- #else
- if ((top > miny) && (top < maxy)) {
- #endif
- if (top > last_top)
- AddFloorDown(last_top, top, x, UPPER_TYPE);
- if (miny < last_miny)
- AddFloorUp(last_miny, miny, x, UPPER_TYPE);
-
- if (top < last_top)
- EndFloorUp(last_top, top, x, UPPER_TYPE);
- if (miny > last_miny)
- EndFloorDown(last_miny, miny, x, UPPER_TYPE);
- } else if (last_top > last_miny)
- EndFloorDown(last_miny, last_top, x, UPPER_TYPE);
- }
-
- last_top = top;
- last_miny = miny;
- last_maxy = maxy;
- last_bottom = bottom;
-
- #if 1
- if (miny < maxy) {
- if ((top < maxy) && (bottom > miny)) {
- if (top < miny)
- top = miny;
- if (bottom > maxy)
- bottom = maxy;
-
- if (top < bottom) {
- if (!wallopt) {
- walls[WallRunCount].top = top;
- walls[WallRunCount].bottom = bottom;
- intersections[int_count[x]][x] = WallRunCount;
- int_count[x]++;
- } else {
- ColDraw(x, top, bottom, (char)Wall.tex_code);
- #if 0
- walltop[x] = top;
- wallbottom[x] = bottom;
- #endif
- }
- }
- }
- }
- if (Wall.type == UPPER_TYPE) {
- if (!wallcol) {
- walls[WallRunCount].tex_num = LEDGE_COLOR;
- }
- if (bottom > miny)
- MinY[x] = bottom;
- } else if (Wall.type == LOWER_TYPE) {
- if (!wallcol) {
- walls[WallRunCount].tex_num = LEDGE_COLOR;
- }
- if (top < maxy)
- MaxY[x] = top;
- } else if (Wall.type == WALL_TYPE) {
- if (!wallcol) {
- walls[WallRunCount].tex_num = WALL_COLOR;
- }
- if (bottom > miny)
- MinY[x] = bottom;
- if (top < maxy)
- MaxY[x] = top;
- #if 0
- if (MaxY[x] < MinY[x])
- MaxY[x] = MinY[x];
- #endif
- }
- #if 0
- }
- }
- }
- #endif
-
- #endif
- if (!wallopt) {
- if (wallcol) {
- walls[WallRunCount].tex_num = Wall.tex_code; /* Added by Johan */
- }
-
- WallRunCount++;
- }
- Wall.y1 += Wall.dy1;
- Wall.y2 += Wall.dy2;
-
- #if 0
- if (MaxY[x] < MinY[x]) {
- printf("?");
- }
- #endif
- }
- #if 0
- printf("\n");
- #endif
-
- if (!nofloor) {
- if ((Wall.type == WALL_TYPE) || (Wall.type == LOWER_TYPE))
- if (last_bottom < last_maxy)
- EndFloorUp(last_maxy, last_bottom, x, LOWER_TYPE);
-
- if ((Wall.type == WALL_TYPE) || (Wall.type == UPPER_TYPE))
- if (last_top > last_miny)
- EndFloorDown(last_miny, last_top, x, UPPER_TYPE);
- }
-
- #if 0
- if (wallopt) {
- for (short x = sx1;x < sx2;x++) {
- ColDraw(x, walltop[x], wallbottom[x], (char)Wall.tex_code);
- }
- }
- #endif
- }
-
-
- /* lb > b */
-
- void AddFloorUp(short lb, short b, short start, short type)
- {
- short row;
-
- char tm = hash(0, type);
-
- if (b < 0)
- b = 0;
- if (lb > height)
- lb = height;
-
- #ifdef COUNT
- addfloor++;
- addfloor_loops += lb - b;
- #endif
-
- for(row = b;row < lb;row++) {
- if (!flooropt) {
- floorlist[row][runcount[row]].start = start;
- floorlist[row][runcount[row]].tex_num = tm; /* Added by Johan */
- } else {
- #if 0
- if (floorlst[row] != -1) {
- printf("!");
- RowDraw(row, start, floorlst[row], tm);
- floorlst[row] = -1;
- } else {
- #endif
- floorlst[row] = start;
- #if 0
- floortex[row] = tm;
- #endif
- #if 0
- }
- #endif
- }
- }
- }
-
-
- /* b > lb */
-
- void AddFloorDown(short lb, short b, short start, short type)
- {
- short row;
-
- char tm = hash(0, type);
-
- if (lb < 0)
- lb = 0;
- if (b > height)
- b = height;
-
- #ifdef COUNT
- addfloor++;
- addfloor_loops += b - lb;
- #endif
-
- for(row = lb;row < b;row++) {
- if (!flooropt) {
- floorlist[row][runcount[row]].start = start;
- floorlist[row][runcount[row]].tex_num = tm; /* Added by Johan */
- } else {
- #if 0
- if (floorlst[row] != -1) {
- printf("!");
- RowDraw(row, start, floorlst[row], tm);
- floorlst[row] = -1;
- } else {
- #endif
- floorlst[row] = start;
- #if 0
- floortex[row] = tm;
- #endif
- #if 0
- }
- #endif
- }
- }
- }
-
-
- /* b < lb */
-
- void EndFloorUp(short lb, short b, short end, short type)
- {
- short row;
- char tm = hash(0, type);
-
- if (b < 0)
- b = 0;
- if (lb > height)
- lb = height;
-
- for(row = b;row < lb;row++) {
- if (!flooropt) {
- floorlist[row][runcount[row]].end = end;
- runcount[row]++;
- } else {
- #if 0
- if (floorlst[row] != -1) {
- #endif
- #if 0
- RowDraw(row, floorlst[row], end, floortex[row]);
- #endif
- RowDraw(row, floorlst[row], end, tm);
- #if 0
- floorlst[row] = -1;
- } else {
- floorlst[row] = end;
- }
- #endif
- }
- }
- }
-
-
- /* b > lb */
-
- void EndFloorDown(short lb, short b, short end, short type)
- {
- short row;
- char tm = hash(0, type);
-
- if (lb < 0)
- lb = 0;
- if (b > height)
- b = height;
-
- for(row = lb;row < b;row++) {
- if (!flooropt) {
- floorlist[row][runcount[row]].end = end;
- runcount[row]++;
- } else {
- #if 0
- if (floorlst[row] != -1) {
- #endif
- #if 0
- RowDraw(row, floorlst[row], end, floortex[row]);
- #endif
- RowDraw(row, floorlst[row], end, tm);
- #if 0
- floorlst[row] = -1;
- } else {
- floorlst[row] = end;
- }
- #endif
- }
- }
- }
-